import { type FC, useEffect } from 'react';
import { useMemoizedFn } from 'ahooks';
import { View, Text } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Animate, { useAnimatedStyle, useSharedValue, withTiming, Easing } from 'react-native-reanimated';
import { errorColor, successColor, warmColor } from '@/constants/Colors';
import type { MessageBoxProps } from './types';
import { isIos } from '@/utils/helper';
import styles from './styles';

const icons = {
  error: 'closecircle',
  success: 'checkcircle',
  info: 'exclamationcircle'
}

const iconColors = {
  error: errorColor,
  success: successColor,
  info: warmColor
}

const duration = 250;
const easing = Easing.bezier(0.42, 0, 0.58, 1.0);

const MessageBox: FC<MessageBoxProps> = (props) => {
  const {
    afterClose,
    type = 'success',
    duration: _duration = 3000
  } = props;

  const { top } = useSafeAreaInsets();
  const open = useSharedValue(false);

  const animateStyle = useAnimatedStyle(() => {
    const opacity = open.value ? 1 : 0;
    const translateY = open.value ? 0 : '-50%';
    const value = withTiming(translateY, { duration, easing });
    const opacityVal = withTiming(opacity, { duration, easing });
    return { transform: [{ translateY: value }], opacity: opacityVal };
  });

  const handleClose = useMemoizedFn(() => {
    open.value = false;
    setTimeout(afterClose, duration);
  });

  const handleOpen = useMemoizedFn(() => {
    requestAnimationFrame(() => {
      open.value = true;
      setTimeout(handleClose, _duration);
    });
  });

  useEffect(handleOpen, [handleOpen]);

  const wrapperStyles = [
    animateStyle,
    styles.message, 
    { top: isIos() ? top: top + 6 }
  ];

  return (
    <Animate.View style={wrapperStyles}>
      <View style={styles.content}>
        <AntDesign
          size={20}
          style={styles.icon}
          color={iconColors[type]}
          name={icons[type] as any}
        />
        <View style={styles.inner}>
          <Text
            numberOfLines={2}
            style={styles.text}
          >
            {props.text}
          </Text>
        </View>
      </View>
    </Animate.View>
  );
}

export default MessageBox;